package cn.hg.solon.youcan.web.admin.controller.monitor;


import org.dromara.hutool.core.text.CharSequenceUtil;
import org.dromara.hutool.core.text.split.SplitUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.MethodType;
import org.noear.solon.core.handle.ModelAndView;
import org.noear.solon.core.handle.Result;
import org.noear.solon.data.annotation.Cache;
import org.noear.solon.data.annotation.CacheRemove;
import org.noear.solon.validation.annotation.NotBlank;
import org.noear.solon.validation.annotation.NotNull;

import com.mybatisflex.core.paginate.Page;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hg.solon.youcan.common.annotation.Log;
import cn.hg.solon.youcan.common.constant.CacheConstants;
import cn.hg.solon.youcan.common.enums.BusinessType;
import cn.hg.solon.youcan.common.web.LayuiPage;
import cn.hg.solon.youcan.job.entity.SysJob;
import cn.hg.solon.youcan.job.service.SysJobService;
import cn.hg.solon.youcan.system.service.SysUserService;
import cn.hg.solon.youcan.web.admin.controller.monitor.qo.JobQueryObject;

/**
 * @author 胡高
 */
@Controller
@Mapping("/admin/monitor/job")
public class JobController extends BaseJobController {

    private static final String SERVICE_NAME = "定时任务";

    private static final String VIEW_PATH = "/admin/monitor/job/";

    @Inject
    SysJobService jobService;

    @Inject
    SysUserService userService;

    /**
     * 跳转到新增页面
     */
    @Mapping(path = "/add", method = MethodType.GET)
    @SaCheckLogin
    public ModelAndView add(Context ctx) {
        this.log.info("跳转到新增[{}]页面", SERVICE_NAME);

        ModelAndView mav = new ModelAndView(VIEW_PATH + "add.html");

        return mav;
    }

    @Mapping(path = "/add", method = MethodType.POST)
    @Log(title = SERVICE_NAME, businessType = BusinessType.CREATE)
    @SaCheckPermission(value = {"monitor:job:add"})
    @CacheRemove(tags = CacheConstants.SYS_JOB_TAG)
    public Result<?> add(Context ctx, @NotNull SysJob bean) {
        this.log.info("新增[{}]记录：bean={}", SERVICE_NAME, bean);

        // 新建记录到数据库
        return this.jobService.save(bean)
            ? Result.succeed() : Result.failure();
    }

    @Mapping(path = "/changeStatus", method = MethodType.GET)
    @Log(title = SERVICE_NAME, businessType = BusinessType.UPDATE)
    @SaCheckPermission(value = {"monitor:job:changeStatus"})
    @CacheRemove(tags = CacheConstants.SYS_JOB_TAG)
    public Result<?> changeStatus(Context ctx, @NotNull Integer id, @NotNull Boolean status) {
        this.log.info("执行[{}]一次：id={}", SERVICE_NAME, id);
        SysJob job = this.jobService.getById(id);
        if (ObjUtil.isNull(job)) {
            return Result.failure("定时任务已经不存在！");
        }

        boolean result = true;
        if (status) {
            result = this.jobService.resume(job);
        } else {
            result = this.jobService.pause(job);
        }

        Result<Boolean> ret = Result.succeed();
        ret.setData(result);

        return result ? ret : Result.failure();
    }

    @Mapping(path = "/delete", method = MethodType.DELETE)
    @Log(title = SERVICE_NAME, businessType = BusinessType.DELETE)
    @SaCheckPermission(value = {"monitor:job:del"})
    @CacheRemove(tags = CacheConstants.SYS_JOB_TAG)
    public Result<?> delete(Context ctx, @NotBlank String ids) {
        this.log.info("删除[{}]记录：ids={}", SERVICE_NAME, ids);

        return this.jobService.removeByIds(SplitUtil.split(ids, ",")) ? Result.succeed()
            : Result.failure();
    }

    /**
     * 跳转到记录展示页面
     */
    @Mapping(path = "/detail", method = MethodType.GET)
    @SaCheckPermission(value = {"monitor:job:query"})
    public ModelAndView detail(Context ctx, @NotNull Integer id) {
        this.log.info("跳转到[{}]展示页面：id={}", SERVICE_NAME, id);

        ModelAndView mav = new ModelAndView(VIEW_PATH + "detail.html");

        mav.put("bean", this.jobService.getById(id));

        return mav;
    }


    /**
     * 跳转到编辑页面
     */
    @Mapping(path = "/edit", method = MethodType.GET)
    @SaCheckLogin
    public ModelAndView edit(Context ctx, @NotNull Integer id) {
        ModelAndView mav = new ModelAndView(VIEW_PATH + "edit.html");

        mav.put("bean", this.jobService.getById(id));

        return mav;
    }

    @Mapping(path = "/edit", method = MethodType.PUT)
    @Log(title = SERVICE_NAME, businessType = BusinessType.UPDATE)
    @SaCheckPermission(value = {"monitor:job:edit"})
    @CacheRemove(tags = CacheConstants.SYS_JOB_TAG)
    public Result<?> edit(Context ctx, @NotNull SysJob bean) {
        this.log.info("更新[{}]记录：bean={}", SERVICE_NAME, bean);

        // 更新到数据库
        return this.jobService.update(bean)
            ? Result.succeed() : Result.failure();
    }

    @Mapping(path = "", method = MethodType.GET)
    @SaCheckLogin
    public ModelAndView index(Context ctx) {
        this.log.info("跳转到[{}]列表页面", SERVICE_NAME);

        ModelAndView mav = new ModelAndView(VIEW_PATH + "index.html");

        // 如果打开列表页面时有参数传递过来，则继续
        mav.putAll(ctx.paramMap());

        return mav;
    }

    /**
     * 分页查询功能
     */
    @Mapping(path = "/query", method = MethodType.POST)
    @SaCheckPermission(value = {"monitor:job:query"})
    @Cache(key = CacheConstants.SYS_JOB_KEY + ":query:${query}", tags = CacheConstants.SYS_JOB_TAG , seconds = CacheConstants.CACHE_SECONDS_ONE_HOUR)
    public LayuiPage<SysJob> query(Context ctx, @NotNull JobQueryObject query) {

        this.log.info("执行[{}]分页查询：query={}", SERVICE_NAME, query);

        query.setSortField(CharSequenceUtil.toUnderlineCase(query.getSortField()));

        /*
         * 服务调用
         */
        Page<SysJob> result =
            this.jobService.pageByMap(new Page<>(query.getPageNumber(), query.getPageSize()), query.toMap());

        /*
         * 返回值处理
         */
        return new LayuiPage<>(result.getRecords(), result.getTotalRow());
    }

    @Mapping(path = "/runOnce", method = MethodType.GET)
    @SaCheckPermission(value = {"monitor:job:changeStatus"})
    public Result<?> runOnce(Context ctx, @NotNull Integer id) {
        this.log.info("执行[{}]一次：id={}", SERVICE_NAME, id);

        SysJob job = this.jobService.getById(id);

        return this.jobService.test(job) ? Result.succeed() : Result.failure();
    }

}
